﻿namespace FSLib

module CommonUtils =

    /// 0xRRGGBBから(r*g*b)のタプル型に変換
    let toRGB i = (i &&& 0xFF0000 >>> 16, i &&& 0x00FF00 >>> 8, i &&& 0x0000FF)

    /// 0xRRGGBBから(r*g*b)のタプル型に変換（float型）
    let toRGBF i = (float(i &&& 0xFF0000 >>> 16), float(i &&& 0x00FF00 >>> 8), float(i &&& 0x0000FF))

    /// (r,g,b)のタプルから0xRRGGBBの値に変換
    let toValue (r,g,b) = (r &&& 0xFF <<< 16) ||| (g &&& 0xFF <<< 8) ||| (b &&& 0xFF)

    /// RGBからHSVに変換
    let rgb2hsv (r,g,b) =
        let (m:float) = min r (min g b)
        let (M:float) = max r (max g b)
        let delta = M - m
        let posh (h:float) = if h < 0.0 then h + 360.0 else h
        let deltaf (f:float) (s:float) = (f-s)/delta
        if M = 0.0 then (-1.0, 0.0, M) else
            let s = (M-m)/M
            if r = M then (posh(60.0 * (deltaf g b)), s, M)
            elif g = M then (posh(60.0 * (2.0 + (deltaf b r))), s, M)
            else (posh(60.0 * (4.0 + (deltaf r g))), s, M)

    /// HSVからRGBに変換
    let hsv2rgb (h,s,v) =
        if s = 0.0 then (v,v,v) else
        let hs = h/60.0
        let i = floor(hs)
        let f = hs-i
        let p = v*(1.0-s)
        let q = v*(1.0-s*f)
        let t = v*(1.0-s*(1.0-f))
        match int i with
            | 0 -> (v,t,p)
            | 1 -> (q,v,p)
            | 2 -> (p,v,t)
            | 3 -> (p,q,v)
            | 4 -> (t,p,v)
            | _ -> (v,p,q)
